package core;

import java.util.LinkedList;

import core.Square.Type;

public class Agent extends AbstractAgent {

	public Agent(int x, int y, int opBound) {
		super(x, y, opBound);

		this.actions = new LinkedList<String>();
		this.goals = new LinkedList<Square.Type>();

		this.goals.add(Square.Type.Meal);
		this.goals.add(Square.Type.Smoking);
		this.goals.add(Square.Type.Meal);
		this.goals.add(Square.Type.Table);
		this.goals.add(Square.Type.Flowers);
		this.goals.add(Square.Type.Entrance);

		this.subgoal = null;
		this.something_has_changed = false;
	}

	public boolean goalReached() {
		if (this.goals.isEmpty()
				&& (subgoal == null || subgoal == Type.Entrance)
				&& this.x == this.perception.floor.rooms.length - 1
				&& perception.floor.isDoor(this.x, this.y)) {
			goalReached = true;
			return true;
		}
		return false;
	}

	public void perceives(Perception perception) {
		this.perception = perception;
	}

	public void update() {
		behaviour();
	}

	public void behaviour() {

		if (subgoal != null
				&& (something_has_changed || this.actions.isEmpty())) {
			
			DlvHandler dlv_handler = new DlvHandler(this, this.perception.floor);
			dlv_handler.writeDl();

			dlv_handler.writeInitialPlan(subgoal.toString());

			this.actions.clear();

			this.actions = dlv_handler.getPlan(dlv_handler.exec(subgoal
					.toString()));

			something_has_changed = false;
			currAction = Action.Type.NOOP;
			
		} else if (this.subgoal == null
				|| perception.floor.get(x, y) == subgoal
				|| (subgoal == Type.Entrance
						&& this.x == this.perception.floor.rooms.length - 1 && perception.floor
						.isDoor(this.x, this.y))) {

			// System.out.println(perception.floor.get(x, y));
			if (subgoal != null)
				currAction = Action.Type.DO;

			this.actions.clear();

			// if there are other subgoals to reach get the next one
			if (!this.goals.isEmpty()) {
				subgoal = this.goals.poll();

				DlvHandler dlv_handler = new DlvHandler(this,
						this.perception.floor);
				dlv_handler.writeDl();

				dlv_handler.writeInitialPlan(subgoal.toString());

				this.actions = dlv_handler.getPlan(dlv_handler.exec(subgoal
						.toString()));

			}
		}
		else if (subgoal != null && !this.actions.isEmpty()) {
			String action = this.actions.poll();
			action = action.substring(5);
			int room = this.perception.floor.get(action.split(",")[0]);
			int cell = Integer.valueOf(action.split(",")[1].substring(0, 1));

			if (this.x > room)
				currAction = Action.Type.NORTH;
			else if (this.x < room)
				currAction = Action.Type.SOUTH;
			else if (this.y > cell)
				currAction = Action.Type.WEST;
			else if (this.y < cell)
				currAction = Action.Type.EAST;
			else
				currAction = Action.Type.NOOP;
		}

	}

	public void showActions() {
		for (int i = 0; i < actionList.size(); i++)
			System.out.println(actionList.get(i).type);
	}

	public Action.Type action() {
		actionList.add(new Action(currAction, x, y));
		return currAction;
	}
}